﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TopDownOperatorPrecedence
{
    public class Program
    {
        static void Main(string[] args)
        {
            //TryParse();
            Interpret();
        }

        private static void TryParse()
        {
            List<PToken> tokens = PToken.TokensFromString(File.ReadAllText(@"e:\code\b.txt"));
            PParser parser = new PParser();
            var node = parser.ParseStatements(tokens);
            File.WriteAllText(@"e:\code\c.txt", node.ToString());
        }

        private static void Interpret()
        {
            PParser parser = new PParser();
            PEnvironment environment = new PEnvironment();
            var normalColor = ConsoleColor.Yellow;
            var errorColor = ConsoleColor.Red;
            var resultColor = ConsoleColor.Green;
            var grayColor = ConsoleColor.Gray;
            Console.ForegroundColor = normalColor;
            Console.WriteLine("--------------------------Lisa 0.01 for test---------------------------");
            Console.WriteLine("------------------------Yet another crap language----------------------");
            Console.WriteLine("----------------------------Slow but works-----------------------------");
            Console.WriteLine();
            Console.WriteLine("-----------------------Procrastination is Masturbation-----------------");
            while (true)
            {
                try
                {
                    Console.ForegroundColor = grayColor;
                    Console.Write(">> ");
                    Console.ForegroundColor = normalColor;
                    string line = Console.ReadLine();
                    if (line.StartsWith(":"))
                    {
                        if (line.StartsWith(":read"))
                        {
                            string path = line.Split(' ')[1];
                            line = File.ReadAllText(path);
                        }
                        else if (line == ":reset")
                        {
                            environment.ClearAll();
                            continue;
                        }
                        else if (line == ":clear")
                        {
                            Console.Clear();
                            continue;
                        }
                        else if (line == ":exit")
                        {
                            break;
                        }
                    }
                    else if (line.EndsWith(" ") || line.EndsWith("{"))
                    {
                        while (line.EndsWith(" "))
                        {
                            Console.ForegroundColor = grayColor;
                            Console.Write("..");
                            Console.ForegroundColor = normalColor;
                            line += Console.ReadLine();
                        }
                    }

                    List<PToken> tokens = PToken.TokensFromString(line);
                    PNode node = parser.ParseStatements(tokens);
                    Console.ForegroundColor = resultColor;
                    if (node is PNodeArray)
                    {
                        foreach (var item in (node as PNodeArray).ArrayObject)
                        {
                            item.Walk(environment);
                        }
                    }
                    else
                    {
                        PObject result = node.Walk(environment);
                        if (result != null)
                        {
                            Console.WriteLine(result.ToString());
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.ForegroundColor = errorColor;
                    Console.WriteLine(ex.Message);
                }
            }
        }
    }

    public static class StringExtensions
    {
        public static string ToStringWithNull(this object value)
        {
            if (value == null)
            {
                return "null";
            }
            else
            {
                return value.ToString();
            }
        }
    }
}
